class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :configure_permitted_parameters, if: :devise_controller?
  after_filter :general_operation_log

  rescue_from CanCan::AccessDenied do
    # flash[:alert] = exception.message
    if request.xhr? # ajax访问的，没有权限返回空数组
      if request.get?
        render json: []
      else
        render json: {status: 0, msg: '没有操作权限'}, status: 403
      end
    else
      flash[:alert] = e.message
      render 'admin/base/access_denied', layout: false
    end
    # redirect_to admin_access_denied_path, alert: exception.message
  end

  # 错误处理 - 全局
  rescue_from Exception do |e|
    begin
      Debug.create(message: e.message, backtrace: e.backtrace, ip: request.ip, user_id: current_user.id, source: request.user_agent)
      GeneralLog.write :error, "#{e.message}\n#{e.backtrace.join('\n')}"
    rescue => ex
      GeneralLog.write :error, "#{ex.message}\n#{ex.backtrace.join('\n')}"
    end
    if request.xhr?
      render json: {status: :error, msg: e.message, trace: e.backtrace.join('\n')}, status: 500
    else
      @message = e.message
      raise e
      # render 'shared/500'
    end
  end

  rescue_from ActiveRecord::RecordNotFound do
    add_breadcrumb '找不到该页面'
    render 'shared/404'
  end

  rescue_from Mysql2::Error do |e|
    add_breadcrumb '请联系管理员'
    if request.xhr?
      render json: {status: :error, msg: e.message, trace: e.backtrace}, status: 500
    else
      @message = e.message
      render 'shared/500'
    end
  end

  def add_breadcrumb(title, src = request.path)
    @breadcrumbs ||= []

    @breadcrumbs << {title: title, src: src}
  end

  def guide
    return render nothing: true if Rails.env != 'development'
    add_breadcrumb '样式', ''
    render 'shared/guide'
  end

  protected

  def create_success_notice(model_name)
    "#{t ('activerecord.models.'<< model_name.to_s)}#{t 'common.create'}#{t 'common.success'}。"
  end

  def update_success_notice(model_name)
    "#{t ('activerecord.models.'<< model_name.to_s)}#{t 'common.update'}#{t 'common.success'}。"
  end

  def destroy_success_notice(model_name)
    "#{t ('activerecord.models.'<< model_name.to_s)}#{t 'common.destroy'}#{t 'common.success'}。"
  end


  def destroy_failed_notice(model)
    str = <<-STR
    <% source_model_name = '#{model.class.name}'%>
    #{model.errors.full_messages.join(', ')}
    STR
    content = ERB.new(str)
    content.result
  end

  def enabled_notice(model_name)
    "#{t ('activerecord.models.'<< model_name.to_s)}#{t 'common.enabled_not'}。"
  end


  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:phone, :email, :password, :password_confirmation, :remember_me) }
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :phone, :email, :password, :remember_me) }
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:phone, :email, :password, :password_confirmation, :current_password) }
  end

  # 添加操作描述
  def operation_desc(value)
    p value
    params[:_operation_desc] = value
  end

  def general_operation_log
    return if current_user.nil?

    module_name=I18n.t("activerecord.models.#{controller_name.singularize}")
    action = I18n.t "common.#{action_name}"
    log = OperationLog.new user_id: current_user.id, name: current_user.name, req_url: request.url, req_method: request.method_symbol,
                           req_ip: request.ip, req_params: params.dup, module: controller_name, operation: action_name, res_status: status

    # 判断最后返回的结果
    result = "#{(200<= status and status <300) ? "成功" : "失败"}"

    # 如果action配置了操作描述, 则取描述
    if params[:_operation_desc]
      log.message = "#{params[:_operation_desc].gsub("%{name}", current_user.name)}"
      log.save
    elsif !module_name.start_with? 'translation missing' and %w(create destroy update).include? action_name
      log.message = "「#{action}」了#{module_name}, #{result}"
      log.save
    end
  end
end
